import {Store} from 'iflux2';
import webApi from './webApi';
import {fromJS} from 'immutable';

import UserActor from './actor/user-actor';
import SearchActor from './actor/search-actor';
import GoodsSearchActor from './actor/goods-search-actor';
import GoodsActor from './actor/goods-actor';
import StepActor from './actor/step-actor';
import TradeActor from './actor/trade-actor';

import {message} from 'antd';

import {UserType, SearchType, GoodsType, GoodsSearchType, StepType, TradeType} from './constant/action-type';

import calculator from 'util/calculator';

export default class AppStore extends Store {
    bindActor() {
        return [
            new UserActor,
            new SearchActor,
            new GoodsActor,
            new GoodsSearchActor,
            new StepActor,
            new TradeActor
        ];
    }

/////////////////////////////////////////会员相关操作/////////////////////////////////////////////////////
    /**
     * 下单步骤
     * @param step
     */
    setStep = async (step)=>{
        const allState = this.state();
        if (step == 'goods') {
            await this.queryGoodsList();
            this.dispatch(StepType.SET_STEP, step);
            await this.getToken(allState.getIn(['chooseUser', 'userId']));
        } else if (step == 'create') {
            await this.cartConfirmCheck();
            this.dispatch(StepType.SET_STEP, step);
            await this.confirmInit();
        }
    }

    previous = async (step)=>{
        if (step == 'user') {
            this.dispatch(GoodsType.RESET_CHOSEN_GOODS);
            this.dispatch(GoodsSearchType.RESET_GOODS_SEARCH);
        }
        this.dispatch(StepType.SET_STEP, step);
    }


    copyTrade = async (tid = '')=>{
        try {
            const {tradeOrder, ...rest} = await webApi.queryDetail(tid);
            this.dispatch(StepType.SET_STEP, "create");
            this.dispatch(StepType.HAS_COPY, true);
            //获取token;
            await this.getToken(tradeOrder.buyUsercode);
            //查询购物车
            await this.confirmInit()
        } catch(err) {
            message.error(err.message);
            return Promise.reject(err);
        }
    }


    getToken = async (userId = '')=>{
        const allState = this.state();

        try {
            const {adminId, token} = await webApi.getToken(userId);
            window.cloudshop_adminId = adminId;
            window.cloudshop_jwtToken = token;
        } catch (err) {
            return Promise.reject(err);
        }
    }


    cartConfirmCheck = async ()=>{
        const allState = this.state();

        let skuList = allState.get('chooseGoods').map((goods)=>{
            return {
                skuId: goods.get('skuId'),
                count: goods.get('itemAmount')
            }
        }).toArray();

        try {
            await webApi.cartConfirmCheck({skuList});
        } catch (err) {
            message.error(err.message);
            return Promise.reject(err);
        }
    }


    confirmInit = async ()=>{
        try {
            const {addressList, goodsMap:{[window.cloudshop_adminId]:{groupGoodsList}}, marketingOrder,
            ships: {[window.cloudshop_adminId]:[...rest]}, invoiceResponseList, payTypes,
                jifen} = await webApi.confirmInit();

            !!addressList && this.dispatch(TradeType.SET_ADDRESS_LIST, fromJS(addressList));
            this.dispatch(TradeType.SET_TRADE_GOODS_LIST, fromJS(groupGoodsList));
            this.dispatch(TradeType.SET_MARKETING_ORDER, fromJS(marketingOrder))
            this.dispatch(TradeType.SET_SHIPS, fromJS(rest));
            this.dispatch(TradeType.SET_INVOICE_LIST, fromJS(invoiceResponseList));
            this.dispatch(TradeType.SET_PAY_TYPES, fromJS(payTypes));
            this.dispatch(TradeType.SET_JIFEN, fromJS(jifen))
            this.queryShipFee();
            this.querySelfAddress();
        } catch (err) {
            message.error(err.message);
            return Promise.reject(err);
        }
    }


    querySelfAddress = async ()=>{
        const params = {
            addressType: 3
        }

        try {
            const selfAddressList = await webApi.querySelfAddress(params);
            this.dispatch(TradeType.SET_SELF_ADDRESS_LIST, fromJS(selfAddressList));
        } catch(err) {
            message.error(err.message);
            return Promise.reject(err);
        }
    }

    setSelfAddressId = (id)=>{
        this.dispatch(TradeType.SET_SELF_ADDRESS_ID, id);
    }


    chooseShippingAddress = (receiptId)=>{
        this.dispatch(TradeType.SET_RECEIPT_ID, receiptId);
        this.queryShipFee();
    }

    chooseShippingType = (id)=>{
        this.dispatch(TradeType.SET_SHIPPING_TYPE, id);
        this.queryShipFee();
    }


    choosePayType = (payTypeId)=>{
        this.dispatch(TradeType.SET_PAY_TYPE_ID, payTypeId);
    }


    queryShipFee = async ()=>{
        const allState = this.state();


        try {
            if (!allState.get('receiptId'))  {
                throw new ReferenceError('暂无收货地址，请先添加地址');
            }
            if (!allState.get('shipId')) {
                throw new ReferenceError('暂无配送方式，请先添加配送方式');
            }
            let params = {
                receiptId: allState.get('receiptId'),
                shipType: [window.cloudshop_adminId, allState.get('shipId')].join(':')
            }
            const {[window.cloudshop_adminId]: {shipFee}} = await webApi.queryShipFee(params);
            this.dispatch(TradeType.SET_SHIP_FEE, shipFee);
            this.dispatch(TradeType.SET_INTEGRAL, undefined);
        } catch (err) {
            if (err instanceof  ReferenceError) {
                message.warn(err.message);
            } else {
                message.error(err.message);
            }
            return Promise.reject(err);
        }
    }


    saveInvoice = (invoice)=>{
        this.dispatch(TradeType.SET_INVOICE, fromJS(invoice));
    }

    chooseCoupon = (couponId)=>{
        this.dispatch(TradeType.SET_COUPON_ID, couponId);
        this.dispatch(TradeType.SET_INTEGRAL, undefined);
    }

    changeUsed = (usedType)=>{
        if (usedType == 'userCoupon') {
            this.dispatch(TradeType.SET_COUPON_ID, undefined);
        }else {
            this.dispatch(TradeType.SET_INTEGRAL, undefined);
        }
    }

    changeIntegral = (integral)=>{
        this.dispatch(TradeType.SET_INTEGRAL, integral);
    }

    setMessage = (msg)=>{
        this.dispatch(TradeType.SET_MESSAGE, msg);
    }

    /**
     * 计算商品总额
     * @returns {*}
     */
    calculateGoodsTotal = ()=>{
        const allState = this.state();

        let total = allState.get('tradeGoodsList').reduce((total, goods)=>{
            let levelPrice = goods.getIn(['goods', 'levelPrice']) || 0;
            let buyCount = goods.getIn(['goods', 'buyCount']) || 1;

            return calculator.floatAdd(total, calculator.floatMul(levelPrice, buyCount));
        }, 0);

        return total;
    }


    /**
     * 计算优惠金额
     * @returns {number}
     */
    calculatePrivilegeTotal = ()=>{
        const allState = this.state();

        const marketingOrder = allState.get('marketingOrder');
        const couponId = allState.get('couponId');

        let privilegeValue = (marketingOrder.get('privilegeValue') || 0);

        let total = calculator.floatAdd(privilegeValue, this.calculateCouponTotal());

        return total;
    }


    /**
     * 计算优惠券金额
     * @returns {number}
     */
    calculateCouponTotal = ()=>{
        const allState = this.state();
        const couponId = allState.get('couponId');
        const marketingOrder = allState.get('marketingOrder');

        let total = 0;

        if (!!couponId)  {
            total =  marketingOrder.get('availableUserCoupons').find(coupon=>coupon.get('couponId') == couponId).get('value');
        }

        return total;
    }

    /**
     * 计算发票费用
     * @returns {number}
     */
    calculateInvoiceTotal = ()=>{
        const allState = this.state();

        const invoiceType = allState.getIn(['invoice', 'invoiceType']);
        const invoiceResponseList = allState.get('invoiceResponseList');

        let total = 0;

        if (!!invoiceType && invoiceType != '0')  {
            let taxPoint = invoiceResponseList.find(invoice=>invoice.get('invoiceType') == invoiceType).get('taxPoint');

            total = calculator.floatSub(this.calculateGoodsTotal(), this.calculatePrivilegeTotal());
            total = calculator.floatSub(total, this.calculateIntegralTotal())
            total = calculator.floatMul(total, taxPoint);
            total = calculator.floatDiv(total, 100);
        }

        return total;
    }


    /**
     * 计算订单总价
     * @returns {number}
     */
    calculateTradeTotal =()=>{
        const allState = this.state();
        let total = calculator.floatAdd(this.calculateGoodsTotal(), calculator.floatAdd(allState.get('shipFee'), this.calculateInvoiceTotal()));
        total = calculator.floatSub(total, (allState.getIn(['marketingOrder', 'privilegeValue']) || 0));

        return total;
    }


    /**
     * 计算积分抵扣金额
     * @returns {number}
     */
    calculateIntegralTotal = ()=>{
        const allState = this.state();
        let jfWorth = allState.getIn(['jifen', 'jfWorth']) || 1;
        let integral = allState.get('integral') || 0;

        let total = calculator.floatDiv(integral, jfWorth);
        return total;
    }


    /**
     * 计算可用积分
     */
    calculateValidIntegralTotal = ()=>{
        const allState = this.state();
        let payFee = calculator.floatSub(this.calculateGoodsTotal(), this.calculatePrivilegeTotal());

        const jifen = allState.get('jifen');

        if (!!jifen && jifen.get('open')) {
            let tradeVal = calculator.floatMul(payFee, jifen.get('tradeVal'));
            let jfWorth = calculator.floatMul(tradeVal, jifen.get('jfWorth'));
            let payValidIntegral = calculator.floatDiv(jfWorth, 100);

            let integral = payValidIntegral >= jifen.get('jfBalance') ? jifen.get('jfBalance') : payValidIntegral;
            return Math.floor(integral * 100) / 100;
        }
        return 0;
    }


    /**
     * 订单应付总额
     * @returns {number}
     */
    calculatePayTotal = ()=>{
        return calculator.floatSub(this.calculateTradeTotal(), calculator.floatAdd(this.calculateIntegralTotal(), this.calculateCouponTotal()))
    }



    saveShippingAddress = async (params)=>{
        try {
            const receiptId = await  webApi.saveReceipt(params);

            const {mailCode, consigneeName, ...rest} = params;
            this.dispatch(TradeType.Add_SHIPPING_ADDRESS, {
                shippingAddress: fromJS(Object.assign({}, rest, {
                    receiptId: (receiptId || params.receiptId),
                    receiptUserName: consigneeName,
                    postcode: mailCode
                })),
                added: !!receiptId
            });
            this.dispatch(TradeType.SET_RECEIPT_ID, (receiptId || params.receiptId));
            await this.queryShipFee();

        } catch (err) {
            message.error(err.message);
            return Promise.reject(err);
        }
    }


    createTrade = async ()=>{
        const allState = this.state();
        let params = {};

        //收货地址
        const receiptId = allState.get('receiptId');
        if (!receiptId) {
            return Promise.reject('请选择收货地址');
        }
        params.receiptId = receiptId;

        //支付方式
        const payType = allState.get('payTypeId');
        if (!payType) {
            return Promise.reject('请先选择支付方式');
        }
        params.paymentType = payType;

        //配送方式
        const shipId = allState.get('shipId');
        if (!shipId) {
            return Promise.reject('请先选择配送方式');
        }
        params.shipType = `${window.window.cloudshop_adminId}:${shipId}`;
        //上门自提
        if (allState.get('ships').find(ship=>ship.get('id') == shipId).get('serviceType') == 'self') {
            const selfId = allState.get('selfId');
            if (!selfId) {
                return Promise.reject('请选择自提地址');
            }
            params.selfReceiptId = selfId;
        }

        if (!!allState.getIn(['marketingOrder', 'presentPackageInfos'])) {
            let presentInfoMap = {};
            allState.getIn(['marketingOrder', 'presentPackageInfos']).forEach((present, mktId)=>{
                let goodsList = present.get('skus')
                    .filter(sku=>!!sku.get('name') && !!sku.get('isCheck'))
                    .map(sku=>sku.getIn(['id', 'goodsId']));

                if (!goodsList.isEmpty()) {
                    presentInfoMap[mktId] = goodsList.toJS();
                }
            })
            params.presentInfoMap = presentInfoMap;
        }

        //发票
        const {invoiceType, invoiceTitle} = allState.get('invoice').toJS();
        if (invoiceType == 1 || invoiceType == 2) {
            params.hasInvoice = 1;
            params.invoiceType = invoiceType;
            params.invoiceTitle = invoiceTitle;
        } else {
            params.hasInvoice = 0;
        }

        //积分抵扣
        params.offsetMoney = Math.floor(this.calculateIntegralTotal() * 100) / 100;
        //优惠券
        const couponId = allState.get('couponId');
        if (!!couponId) {
            params.couponCodeId = couponId;
        }

        const msg = allState.get('message');
        if (!!msg) {
            params.messageMap = {
                [window.window.cloudshop_adminId]: msg
            }
        }

        try {
            await webApi.createTrade(params);
        } catch(err) {
            message.error(err.message);
            return Promise.reject(err.message);
        }
    }







    /**
     * 查询会员列表
     * @param params
     * @returns {Promise.<void>}
     */
    queryUsers = async ()=>{
        const allState = this.state();

        let params = {
            pageSize: allState.getIn(['search', 'pagination', 'pageSize']),
            pageNum: allState.getIn(['search', 'pagination', 'pageNum']) - 1,
            searchValue: allState.getIn(['search', 'searchValue'])
        };

        try {
            const {dataList, ...rest} = await webApi.queryUsers(params);
            rest.pageNum += 1;
            this.dispatch(UserType.SET_USERS, fromJS(dataList));
            this.dispatch(SearchType.CHANGE_SEARCH_PAGE_PARAM, fromJS(rest));
        }catch (err) {
            message.error(err.message);
            return Promise.reject(err);
        }
    }


    /**
     * 设置分页信息
     * @param pagination
     */
    setPagination = (pagination)=>{
        this.dispatch(SearchType.CHANGE_SEARCH_PAGE_PARAM, fromJS(pagination));
    }


    /**
     * 重置分页信息
     */
    resetPagination = ()=>{
        this.dispatch(SearchType.RESET_SEARCH_PAGINATION_PARAM);
    }


    /**
     * 设置搜索条件
     * @param value
     */
    setSearchValue = (value)=>{
        this.dispatch(SearchType.SET_SEARCH, value);
    }


    /**
     * 选择会员
     * @param user
     */
    chooseUserOpt = (user)=>{
        this.dispatch(UserType.SET_CHOOSE, user);
    }


    /**
     * 重置会员信息
     */
    resetChooseUserOpt = ()=>{
        this.dispatch(UserType.RESET_CHOOSE);
    }

///////////////////////////////////商品操作/////////////////////////////////////////////////////////
    /**
     * 查询商品列表
     * @returns {Promise.<void>}
     */
    queryGoodsList = async ()=>{
        const allState = this.state();

        let params = {
            pageSize: allState.getIn(['goodsSearch', 'pagination', 'pageSize']),
            pageNum: allState.getIn(['goodsSearch', 'pagination', 'pageNum']),
            searchValue: allState.getIn(['goodsSearch', 'searchValue']),
            scene: allState.getIn(['goodsSearch', 'showType'])
        };

        try {
            const {dataList, ...rest} = await webApi.queryGoodsList(params);
            this.dispatch(GoodsType.SET_GOODS, fromJS(dataList));
            rest.pageNum += 1;
            this.dispatch(GoodsSearchType.CHANGE_GOODS_SEARCH_PAGINATION, fromJS(rest));
        }catch (err){
            message.error(err.message);
            return Promise.reject(err);
        }
    }


    /**
     * 点击下页
     * @param params
     */
    changeGoodsPagination = (params)=>{
        this.dispatch(GoodsSearchType.CHANGE_GOODS_SEARCH_PAGINATION, fromJS(params));
    }


    /**
     * 重置分页信息
     */
    resetGoodsPagination = ()=>{
        this.dispatch(GoodsSearchType.RESET_GOODS_SEARCH_PAGINATION);
    }


    /**
     * 设置查询关键字
     * @param value
     */
    setGoodsSearchValue = (value)=>{
        this.dispatch(GoodsSearchType.SET_GOODS_SEARCH_VALUE, value);
    }


    /**
     * 设置展现方式
     * @param type
     */
    setGoodsShowType = (type)=>{
        this.dispatch(GoodsSearchType.SET_GOODS_SEARCH_TYPE, type)
    }


    /**
     * 选择商品
     * @param goods
     */
    addGoods = (goods)=>{
        this.dispatch(GoodsType.SET_CHOOSE_GOODS, fromJS([goods.set('itemAmount', 1)]));
    }


    /**
     * 删除选择商品
     * @param index
     */
    deleteChooseGoods = (index)=>{
        this.dispatch(GoodsType.DELETE_CHOOSE_GOODS, index)
    }


    /**
     * 修改商品数量
     * @param index
     * @param itemAmount
     */
    changeNum = (index, itemAmount)=>{
        this.dispatch(GoodsType.CHANGE_NUM, {index, itemAmount});
    }
}